package com.dalin.framework.threadpool;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * @description: 线程池配置https://blog.csdn.net/coderrrrrr/article/details/138387442
 * @author Najl
 * @date 2023/3/14 14:17
 */
@Configuration
@EnableAsync
public class AsyncConfig {

    @Bean(name = "taskExecutor")
    public Executor threadPoolTaskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        // 核心线程数，指的是核心线程大小，线程池中维护一个最小的线程数量，即使这些线程处于空闲状态，也一直存在池中，除非设置了核心线程超时时间。
        executor.setCorePoolSize(10);
        // 最大线程数，指的是线程池中允许创建的最大线程数，如果当前线程池中的线程数量达到了最大值，那么新来的任务会被拒绝执行，并且抛出RejectedExecutionException异常。
        executor.setMaxPoolSize(300);
        // 队列容量，指的是线程池中任务队列的大小，当线程池中的线程数量达到最大值时，新来的任务会被放到任务队列中等待执行，任务队列的大小决定了线程池能够处理的最大并发任务数。
        executor.setQueueCapacity(100); //
        // 线程存活时间，指的是线程池中线程的存活时间，如果线程池中的线程没有任务执行，那么这些线程将会被回收,并且等待时间超过了指定的时间后，这些线程将会被回收。
        // 单位是秒
        executor.setKeepAliveSeconds(600);
        // 线程名前缀，指的是线程池中线程的名称前缀，每个线程都有一个唯一的名字，这个名字就是线程名前
        executor.setThreadNamePrefix("NajlThreadPoolTaskExecutor-");
        // 拒绝策略，当线程池中的线程数量达到最大值时，新来的任务会被拒绝执行，并且抛出RejectedExecutionException异常。
        // 默认情况下，线程池使用的是AbortPolicy策略，即直接抛出RejectedExecutionException异常，这种策略比较简单粗暴，但是可以保证线程池不会有任何任务丢失。
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); // 拒绝策略
        // 初始化线程池,初始化线程池中的线程，并且启动这些线程
        executor.initialize();
        return executor;
    }
}